﻿
using HBase;
using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Security.Cryptography;
using static System.Net.Mime.MediaTypeNames;

namespace hCommand {
    public class WcsLoadUp : ZtTask {

        private IWCSServer wcsServer = WMSDalFactray.getDal<IWCSServer>();
        ICoreTaskServer taskServer = WMSDalFactray.getDal<ICoreTaskServer>();

       public bool taskLoaded=false;
        public WcsLoadUp() {
            time = 1000;
        } 
        //缓存 CoreWhLoc BStn  BStnRelation CoreTaskParam，node
        protected override bool onlyOneTimeAsync() { 
        
            loadCacheData(); 
            initGraph(); 
            LoadParam();
            return true;
        }

        void loadCacheData() {
            List<BParam> list = wcsServer.getParams();
            MyCache.addOver(list);
            consoleOnly(InfoCode.consleOnly_init_loc, "开始加载货位");
            List<CoreWhLoc> res = taskServer.GetAll<CoreWhLoc>();
            MyCache.addOver(res);
            consoleOnly(InfoCode.consleOnly_init_stn, "开始加载站台");
            MyCache.addOver(wcsServer.GetPhysicalStns());
            consoleOnly(InfoCode.consleOnly_init_rela, "开始加载站台关系");
            MyCache.addOver(wcsServer.GetPhysicalStnRelation());
        }

        void getAgv2Node(BStn stn, int eid) {
            Node node = Node.getNode(eid);
            if (node == null) {
                node = new Node(stn, eid);
                MyCache.addOver(node);
            }
           
        }
        private void initGraph() {
            List<BStn> physicalStns = MyCache.getList<BStn>();
            for (int i= 0;i< physicalStns.Count;i++) {
                addStn( physicalStns[i]);
            }
            List<BStnRelation> stnRelations = MyCache.getList<BStnRelation>();
            foreach (BStnRelation physical in stnRelations) {
                addQueue(physical);
            }

            List<Node> nodeList = MyCache.getList<Node>();
            foreach (Node node in nodeList) {
                analysisType(node);
            }
            
            foreach (Node node in nodeList) {
                transmitEnd(node);
            }
        }


       void  transmitEnd(Node node) {
            if (node.type != NodeType.死胡同) {
                return;
            }
            if (node.getBeforeEdge().Count != 1) {
                return;
            }
            List<Edge> nextEdge = node.getNextEdge();
            Node next0 =  nextEdge[0] .desNode;
          
           transmitEnd(node, next0);
        }

        void transmitEnd(Node before, Node node) {
            if (node.type == NodeType.双向管道) {
                node.type = NodeType.死胡同;
                List<Edge> nextEdge = node.getNextEdge();
                Node next0 = nextEdge[0].desNode;
                Node next1 = nextEdge[1].desNode;
                if (next0 == before) {
                    transmitEnd(node, next1);
                } else if (next1 == before) {
                    transmitEnd(node, next0);
                }else
                {
                    throw new Exception("relation error"+node.getId());
                }

            }
        }





        void analysisType(Node node) {

            List<Edge> nextEdgeIds = node.getNextEdge();
            List<Edge> beforeEdgeIds = node.getBeforeEdge();
            int nextCount = nextEdgeIds.Count;
            int beforeCount = beforeEdgeIds.Count;
            if (nextCount > 2 || beforeCount > 2) {
                node.type = NodeType.岔路口;
            } else if (nextCount == 2 && beforeCount == 2) {
                Node next0 = nextEdgeIds[0].desNode;
                Node next1 = nextEdgeIds[1].desNode;
                Node before0 = beforeEdgeIds[0].srcNode;
                Node before1 = beforeEdgeIds[1].srcNode;
                if (next0 == before0 && next1 == before1 || next0 == before1 && next1 == before0) {

                    node.type = NodeType.双向管道;
                } else {
                    node.type = NodeType.岔路口;
                }
            } else if (nextCount == 1 && beforeCount == 2|| nextCount == 2 && beforeCount == 1) { 
                node.type = NodeType.岔路口; 
            } else if (nextCount == 1 && beforeCount == 1) {
                Node next0 = nextEdgeIds[0].desNode;
                Node before0 = beforeEdgeIds[0].srcNode;
                if (next0 == before0) {
                    node.type = NodeType.死胡同;
                } else {
                    node.type = NodeType.单向管道;
                }

            } else {

                fileAll(InfoCode.fileAll_node_relay_Chech,"{0}node类型异常入{1}出{2}", node.id,beforeCount,nextCount);
            }

            foreach (Edge nextEdge in nextEdgeIds) {
          
                Node next0 = nextEdge.desNode;
                foreach (Edge beforeEdge in nextEdgeIds) {
      
                    if (beforeEdge.srcNode == next0) {
                        beforeEdge.reverseEdge = nextEdge;
                        nextEdge.reverseEdge = beforeEdge;

                    }
                }
            }

        }

        private void  addStn(BStn stn) {
       
            if (stn.type == 1 || stn.type == 0) {
                Node node = Node.getNode((int)stn.id);
                if (node == null) {
                    node = new Node(stn);
                    MyCache.addOver(node);
                } else {
                    fileAll(InfoCode.fileAll_node_double,"id{0} 重复加载BStn", stn.id);
                }
            } else if (stn.type == 2) {
                int eidUp = (int)stn.id * 10 + 1;
                int eidRight = eidUp + 2;
                int eidDown = eidUp + 4;
                int eidleft = eidUp + 6;

                getAgv2Node(stn, eidUp);
                getAgv2Node(stn, eidRight);
                getAgv2Node(stn, eidDown);
                getAgv2Node(stn, eidleft);

                addAgvV2Queue(eidUp, eidUp - 100000, stn);
                addAgvV2Queue(eidUp + 100000, eidUp, stn);

                addAgvV2Queue(eidRight, eidRight + 10, stn);
                addAgvV2Queue(eidRight - 10, eidRight, stn);

                addAgvV2Queue(eidDown, eidDown + 100000, stn);
                addAgvV2Queue(eidDown - 100000, eidDown, stn);

                addAgvV2Queue(eidleft, eidleft - 10, stn);
                addAgvV2Queue(eidleft + 10, eidleft, stn);

                addAgvV2Queue(eidUp, eidRight, stn);
                addAgvV2Queue(eidRight, eidDown, stn);
                addAgvV2Queue(eidDown, eidleft, stn);
                addAgvV2Queue(eidleft, eidUp, stn);
            }

        }
        public static void addQueue(BStnRelation physical) {

            Node b = Node.getConfig(physical.src);
            Node t = Node.getConfig(physical.next);
            if (b == null || t == null) {
                throw new Exception("配置路径异常" + physical.id);
            }
            foreach (Edge edgeOrder in b.getNextEdge()) {
           
                if (edgeOrder != null && edgeOrder.getDes() == t) {
                    return;
                }
            }
            MyCache.addOver(new Edge(b, physical, physical.deviceType, t));
        }
        public  void addAgvV2Queue(int src, int des, BStn stn) {

            Node b = Node.getNode(src);
            Node t = Node.getNode(des);

            if (t == null || b == null) {
                return;
            }
            foreach (Edge e in b.getNextEdge()) {
               
                if (e != null && e.getDes() == t) {
                    return;
                }
            }
            MyCache.addOver(new Edge(b, stn.distance, 0,  "TaskAgvV2", t));
        }
        private void LoadParam() {
            List<CoreTaskParam> pars = taskServer.GetAll<CoreTaskParam>(String.Format(" and status>={0} and status< {1}", (int)CoreTaskParamStatus.下发完成, (int)CoreTaskParamStatus.执行完成));
            console(0, "初始化任务"+ pars.Count);
            MyCache.addOver(pars);
            List<CoreTaskParam> paramList = MyCache.getList<CoreTaskParam>();
            foreach (CoreTaskParam p in paramList) {
                CoreTask complete = taskServer.getById<CoreTask>(p.taskId);
                PathFacade.splitParam(p, complete);
            }
            taskLoaded = true;
        }
      public void  reloadParam() {
          
            if (taskLoaded) {
                return;
            }
            List<CoreTaskParam>  paramList= MyCache.getList<CoreTaskParam>();
            foreach (CoreTaskParam p in paramList) {
                PathFacade.removeParam(p); 
            } 
            LoadParam();
            console(0, "重新加载缓存");
        }
        public override bool excute() {
            reloadParam();
    
            List<CoreTaskParam> list = taskServer.getWorkingTaskParam();
            if (null == list || list.Count == 0) {
                return true;
            }
            foreach (CoreTaskParam param in list) {
                oneParam(param, list);
                return true;
            }
            return true;
        }

        void oneParam(CoreTaskParam param, List<CoreTaskParam> list) {
            for (int i = 0; i < list.Count; i++) {
                CoreTaskParam realyParam = list[i];
                if (param.getRelay().Contains( realyParam.id) && realyParam.status < (int)CoreTaskParamStatus.下发完成) {
                    return;
                }
            }
            MyCache.addOver(param);
            bool split = taskServer.splitParam(param.id);
            if (split) {
                if (!BaseConfig.serversStarts) {
                    taskServer.updateTaskParamStatus(param.id, CoreTaskParamStatus.下发完成);
                }
               
            }
        }
    }
}
